
using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using Sedna.Core;
using Sedna.Core.Event;

namespace Sedna.Core.Event
{
    /// <summary>
    /// Send event to xml file
    /// </summary>
    public class XmlEventSender : IEventSender
    {
        private static int fileOrder = 1;
        
        private String directory;

        public string Directory
        {
            get { return directory; }
            set { directory = value; }
        }

        public void Send(IEvent eventObject)
        {
            String fileName = CreateFilePath(eventObject);
            XmlWriter xmlWriter = XmlWriter.Create(fileName);
            new XmlSerializer(eventObject.GetType())
                .Serialize(xmlWriter, eventObject);
            xmlWriter.Close();
            if (eventObject is BaseEvent)
            {
                Validate((BaseEvent)eventObject, fileName);
            }
        }

        private String CreateFilePath(IEvent eventObject)
        {
            String result = null;
            BaseEvent curEvent = eventObject as BaseEvent;
            lock (typeof(XmlEventSender))
            {
                result = String.Format(@"{0}\{1}-{2}.{3}.xml", directory, curEvent == null ? "event" : curEvent.Name, 
                                       fileOrder++, DateTime.Now.Ticks );
            }
            return result;
        }

        private void Validate(BaseEvent baseEvent, String fileName)
        {
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ValidationType = ValidationType.Schema;
            settings.Schemas = baseEvent.ValidateSchemaSet();
            settings.ValidationEventHandler += new ValidationEventHandler(XmlValidationEventHandler);

            XmlReader xmlReader = XmlReader.Create(fileName, settings);
            while (xmlReader.Read());
        }

        private void XmlValidationEventHandler(object sender, ValidationEventArgs e)
        {
            throw new SednaException(String.Format("Xml Validation: {0}", e.Message));
        }
    }
}
